//Base32 字符映射表
const BASE32_TABLE = '9876543210mnbvcxzasdfghjklpoiuyt';
// const BASE32_TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
//保证二进制字符串长度为8位是为了确保每个字符的二进制表示都是一致的，方便后续处理或存储。
//因为在计算机中，每个字符通常占用一个字节（8位），这样做可以使得输出的二进制字符串更加规范和统一。
/**
 * 编码
 * @param inputStr
 * @returns {string}
 */
function encodeBase32(inputStr) {
  // 1. 将字符串转换为 ASCII 编号
  let asciiStr = '';
  for (let char of inputStr) {
    // 将字符转换为ASCII码，然后将ASCII码转换为二进制字符串
    // 使用padStart方法确保每个字符的二进制表示都是8位（bit），不足8位在前面补充0
    asciiStr += char.charCodeAt(0).toString(2).padStart(8, '0');
  }

  // 2. 将 ASCII 编号转换为二进制表示
  let binaryStr = asciiStr;


  // 3. 在末尾补 0 使二进制字符串长度能被 5 整除
  const remainder = binaryStr.length % 5;
  if (remainder) {
    binaryStr += '0'.repeat(5 - remainder);
  }



  // 4. 将二进制字符串以 5 bit 为一组进行分组
  //每 5 bit 为一组，表示为：01100 11001 10111 10110 11110
  let encoded = '';
  for (let i = 0; i < binaryStr.length; i += 5) {
    // 从二进制字符串中截取5位，并转换为十进制数字
    const index = parseInt(binaryStr.substring(i, i + 5), 2);
    // 将十进制数字对应的BASE32字符添加到编码后的字符串中
    encoded += BASE32_TABLE[index];
  }

  // 5. 根据原始二进制数据的位数除以 40 后的余数，确定末尾需要补 + 的数目
  // 获取原始ASCII字符串的长度
  const originalLength = asciiStr.length;
  // 计算原始长度对40取余的结果，用于后续处理中的对齐或填充操作
  const remainder40 = originalLength % 40;


  // 6. 补 + 符号
  // 如果原始二进制数据 bit 数目除以 40 后的余数是 0 的话，不需要补 +
  if(remainder40===0){
     encoded = encoded
  }
  // 如果原始二进制数据 bit 数目除以 40 后的余数是 8 的话，补 6 个 +
  if(remainder40===8){
     encoded += '+'.repeat(6);
  }
  // 如果原始二进制数据 bit 数目除以 40 后的余数是 16 的话，补 4 个 +
  if(remainder40===16){
    encoded += '+'.repeat(4);
  }
  // 如果原始二进制数据 bit 数目除以 40 后的余数是 24 的话，补 3 个 +
  if(remainder40===24){
    encoded += '+'.repeat(3);
  }
  // 如果原始二进制数据 bit 数目除以 40 后的余数是 32 的话，补 1 个 +
  if(remainder40===32){
    encoded += '+'.repeat(1);
  }

  return encoded;
}

// 01100
// 11001
// 10111
// 10110
// 11110

function decodeBase32(encodedStr) {
  // 输入：bljhy+++
  // 查询索引 - 字符转换表后，可知原始的二进制数据组为：01100 11001 10111 10110 11110
  // 由末尾 3 个 + 可知在编码时原始二进制数据最后一组的个数为 24 个，由此可知最后一组数据为：01100110 01101111 01101111
  // 将二进制数据转换为 ASCII 编号后可知，原始字符串的 Unicode 序列为：102 111 111
  // 将 Unicode 序列转换为字符串，即可得出原始字符串，为：foo

  // 1. 移除末尾的填充符号 '+'
  encodedStr = encodedStr.replace(/\++$/, '');
  console.log(JSON.stringify(encodedStr));


  // 2. 将Base32字符转换为二进制字符串
  let binaryStr = '';
  for (let char of encodedStr) {
    // 查找字符在 BASE32_TABLE 中的索引
    const index = BASE32_TABLE.indexOf(char);
    // 将索引转换为5位的二进制字符串
    binaryStr += index.toString(2).padStart(5, '0');
    // binaryStr += char.charCodeAt(0).toString(2).padStart(8, '0');
  }

  console.log(JSON.stringify(binaryStr),'ssss');
  // binaryStr =  binaryStr.replace(/-/g, '');
  // console.log(JSON.stringify(binaryStr),'aaa');

  // 3. 去除末尾多余的0位
  while (binaryStr.length % 8 !== 0) {
    binaryStr = binaryStr.slice(0, -1);
  }
  // 4. 将二进制字符串转换为ASCII字符串
  let decoded = '';
  for (let i = 0; i < binaryStr.length; i += 8) {
    // 截取8位二进制字符串并转换为十进制数字
    const asciiCode = parseInt(binaryStr.substring(i, i + 8), 2);
    // 将ASCII码转换为字符并添加到结果字符串中
    decoded += String.fromCharCode(asciiCode);
  }
  console.log(JSON.stringify(decoded,'decoded'));

  return decoded;
}


// 编码
// const inputStr = "111."
// const encodedStr = encodeBase32(inputStr);
// console.log("编码结果:", encodedStr);

// 解码bljhy+++b0zj5+++
const decodedStr = decodeBase32("bljhy+++bljhy+++");
// console.log(JSON.stringify(decodedStr));
// console.log(JSON.stringify("foofoo"));
console.log("解码结果:", decodedStr); // 应输出 foobar
console.log("是否相等:", decodedStr == "foofoo"); //
//不支持中文
// console.log("是否相等:", decodedStr===inputStr);


